<!--------------------------------
 - @Author: Your Name
 - @LastEditor: Your Name
 - @LastEditTime: 2025-11-07
 - Copyright © 2025 Your Name
 --------------------------------->

<template>
  <CommonPage>
    <NTabs v-model:value="activeTab" type="line" animated>
      <NTabPane name="api-keys" tab="API密钥管理">
        <template #action>
          <NButton v-permission="'AddApiKey'" type="primary" @click="handleAdd()">
            <i class="i-material-symbols:add mr-4 text-18" />
            创建API密钥
          </NButton>
        </template>

        <MeCrud
          ref="$table"
          v-model:query-items="queryItems"
          :scroll-x="1600"
          :columns="apiKeyColumns"
          :get-data="api.read"
        >
          <MeQueryItem label="密钥名称" :label-width="70">
            <n-input
              v-model:value="queryItems.name"
              type="text"
              placeholder="请输入密钥名称"
              clearable
            />
          </MeQueryItem>

          <MeQueryItem label="API密钥" :label-width="70">
            <n-input
              v-model:value="queryItems.apiKey"
              type="text"
              placeholder="请输入API密钥"
              clearable
            />
          </MeQueryItem>

          <MeQueryItem label="状态" :label-width="70">
            <n-select
              v-model:value="queryItems.status"
              :options="[
                { label: '启用', value: 'ENABLED' },
                { label: '禁用', value: 'DISABLED' },
              ]"
              clearable
              placeholder="请选择状态"
            />
          </MeQueryItem>
        </MeCrud>
      </NTabPane>

      <NTabPane name="usage-stats" tab="使用统计">
        <NCard title="API使用统计" segmented class="mb-12">
          <NGrid :cols="4" :x-gap="12" :y-gap="12">
            <NGridItem>
              <NStatistic label="总请求数" :value="statsData.totalRequests" />
            </NGridItem>
            <NGridItem>
              <NStatistic label="成功请求数" :value="statsData.successfulRequests" />
            </NGridItem>
            <NGridItem>
              <NStatistic label="失败请求数" :value="statsData.failedRequests" />
            </NGridItem>
            <NGridItem>
              <NStatistic label="平均响应时间" :value="statsData.avgResponseTime">
                <template #suffix>
                  ms
                </template>
              </NStatistic>
            </NGridItem>
          </NGrid>

          <div class="mt-12 h-400">
            <VChart :option="chartOption" autoresize />
          </div>
        </NCard>

        <MeCrud
          ref="$statsTable"
          v-model:query-items="statsQueryItems"
          :scroll-x="1200"
          :columns="statsColumns"
          :get-data="api.getUsageStats"
        >
          <MeQueryItem label="API密钥" :label-width="70">
            <n-select
              v-model:value="statsQueryItems.apiKey"
              :options="apiKeysForStats"
              label-field="name"
              value-field="id"
              clearable
              placeholder="请选择API密钥"
              filterable
            />
          </MeQueryItem>

          <MeQueryItem label="时间范围" :label-width="70">
            <NDatePicker
              v-model:value="statsTimeRange"
              type="daterange"
              clearable
              format="yyyy-MM-dd"
              @update:value="handleStatsTimeRangeChange"
            />
          </MeQueryItem>
        </MeCrud>
      </NTabPane>
    </NTabs>

    <MeModal ref="modalRef" width="700px">
      <n-form
        ref="modalFormRef"
        label-placement="left"
        label-align="left"
        :label-width="120"
        :model="modalForm"
        :disabled="modalAction === 'view'"
      >
        <n-form-item
          label="密钥名称"
          path="name"
          :rule="{
            required: true,
            message: '请输入密钥名称',
            trigger: ['input', 'blur'],
          }"
        >
          <n-input v-model:value="modalForm.name" placeholder="请输入密钥名称" />
        </n-form-item>

        <n-form-item label="密钥描述" path="description">
          <n-input
            v-model:value="modalForm.description"
            type="textarea"
            :autosize="{ minRows: 3, maxRows: 5 }"
            placeholder="请输入密钥描述"
          />
        </n-form-item>

        <n-form-item label="API密钥">
          <n-input v-model:value="modalForm.apiKey" placeholder="API密钥将在创建后生成" :readonly="true" />
        </n-form-item>

        <n-form-item label="权限范围" path="permissions">
          <n-select
            v-model:value="modalForm.permissions"
            :options="permissionOptions"
            label-field="name"
            value-field="value"
            multiple
            filterable
            placeholder="请选择权限范围"
          />
        </n-form-item>

        <n-form-item label="IP白名单" path="ipWhitelist">
          <NDynamicTags v-model:value="modalForm.ipWhitelist" :input-props="{ placeholder: '请输入IP地址' }" />
        </n-form-item>

        <n-form-item label="IP黑名单" path="ipBlacklist">
          <NDynamicTags v-model:value="modalForm.ipBlacklist" :input-props="{ placeholder: '请输入IP地址' }" />
        </n-form-item>

        <n-form-item label="限流配置">
          <NCard>
            <n-form :model="modalForm.rateLimitConfig" label-placement="left" :label-width="100">
              <n-form-item label="每秒请求数" path="requestsPerSecond">
                <n-input-number
                  v-model:value="modalForm.rateLimitConfig.requestsPerSecond"
                  :min="1"
                  :max="10000"
                  placeholder="请输入每秒请求数"
                />
              </n-form-item>
              <n-form-item label="每分钟请求数" path="requestsPerMinute">
                <n-input-number
                  v-model:value="modalForm.rateLimitConfig.requestsPerMinute"
                  :min="1"
                  :max="100000"
                  placeholder="请输入每分钟请求数"
                />
              </n-form-item>
              <n-form-item label="每小时请求数" path="requestsPerHour">
                <n-input-number
                  v-model:value="modalForm.rateLimitConfig.requestsPerHour"
                  :min="1"
                  :max="1000000"
                  placeholder="请输入每小时请求数"
                />
              </n-form-item>
            </n-form>
          </NCard>
        </n-form-item>

        <n-form-item label="过期时间" path="expireTime">
          <NDatePicker
            v-model:value="modalForm.expireTime"
            type="datetime"
            clearable
            format="yyyy-MM-dd HH:mm:ss"
            placeholder="请选择过期时间"
          />
        </n-form-item>

        <n-form-item label="状态" path="status">
          <NSwitch v-model:value="modalForm.status" checked-value="ENABLED" unchecked-value="DISABLED">
            <template #checked>
              启用
            </template>
            <template #unchecked>
              禁用
            </template>
          </NSwitch>
        </n-form-item>
      </n-form>
    </MeModal>
  </CommonPage>
</template>

<script setup>
import { BarChart, LineChart, PieChart } from 'echarts/charts'
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
import * as echarts from 'echarts/core'
import { UniversalTransition } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import { NButton, NCard, NDatePicker, NDynamicTags, NGrid, NGridItem, NStatistic, NSwitch, NTabPane, NTabs, NTag } from 'naive-ui'
import VChart from 'vue-echarts'
import { MeCrud, MeModal, MeQueryItem } from '@/components'
import { useCrud } from '@/composables'
import { formatDateTime, formatNumber } from '@/utils'
import api from './api'

defineOptions({ name: 'ApiManagementMgt' })

const activeTab = ref('api-keys')

// API密钥相关
const $table = ref(null)
const queryItems = ref({})

// 使用统计相关
const $statsTable = ref(null)
const statsQueryItems = ref({})
const statsTimeRange = ref(null)

// 图表相关
echarts.use([
  TooltipComponent,
  GridComponent,
  LegendComponent,
  BarChart,
  LineChart,
  CanvasRenderer,
  UniversalTransition,
  PieChart,
])

// 统计数据
const statsData = ref({
  totalRequests: 0,
  successfulRequests: 0,
  failedRequests: 0,
  avgResponseTime: 0,
})

// API密钥列表（用于统计筛选）
const apiKeysForStats = ref([])

const chartOption = computed(() => {
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        crossStyle: {
          color: '#999',
        },
      },
    },
    legend: {
      data: ['总请求数', '成功请求数', '失败请求数'],
    },
    xAxis: [
      {
        type: 'category',
        data: ['1月', '2月', '3月', '4月', '5月', '6月'],
        axisPointer: {
          type: 'shadow',
        },
      },
    ],
    yAxis: [
      {
        type: 'value',
        name: '请求数',
        min: 0,
        axisLabel: {
          formatter: '{value}',
        },
      },
    ],
    series: [
      {
        name: '总请求数',
        type: 'line',
        data: [2000, 3200, 5200, 5500, 6000, 8050],
      },
      {
        name: '成功请求数',
        type: 'line',
        data: [1800, 3000, 5000, 5200, 5800, 7800],
      },
      {
        name: '失败请求数',
        type: 'line',
        data: [200, 200, 200, 300, 200, 250],
      },
    ],
  }
})

onMounted(() => {
  $table.value?.handleSearch()
  loadApiKeyOptionsForStats()
  loadStatsData()
})

// 加载API密钥选项用于统计筛选
async function loadApiKeyOptionsForStats() {
  try {
    // 这里我们使用现有的API密钥列表
    apiKeysForStats.value = [
      { id: 1, name: '前端应用API密钥' },
      { id: 2, name: '移动端API密钥' },
      { id: 3, name: '后端服务API密钥' },
    ]
  }
  catch (error) {
    console.error('加载API密钥选项失败:', error)
  }
}

// 加载统计数据
async function loadStatsData() {
  try {
    // 模拟统计数据
    statsData.value = {
      totalRequests: 24567,
      successfulRequests: 24012,
      failedRequests: 555,
      avgResponseTime: 125,
    }
  }
  catch (error) {
    console.error('加载统计失败:', error)
  }
}

// 权限选项
const permissionOptions = ref([])
api.getPermissionOptions().then(({ data = [] }) => (permissionOptions.value = data))

const {
  modalRef,
  modalFormRef,
  modalForm,
  modalAction,
  handleAdd,
  handleDelete,
  handleOpen,
  handleSave,
} = useCrud({
  name: 'API密钥',
  initForm: {
    status: 'ENABLED',
    permissions: [],
    ipWhitelist: [],
    ipBlacklist: [],
    rateLimitConfig: {
      requestsPerSecond: 100,
      requestsPerMinute: 1000,
      requestsPerHour: 10000,
    },
  },
  doCreate: api.create,
  doDelete: api.delete,
  doUpdate: api.update,
  refresh: () => $table.value?.handleSearch(),
})

// API密钥列配置
const apiKeyColumns = [
  { title: '密钥名称', key: 'name', width: 150, ellipsis: { tooltip: true } },
  {
    title: 'API密钥',
    key: 'apiKey',
    width: 250,
    ellipsis: { tooltip: true },
    render: row => h('span', row.apiKey ? `${row.apiKey.substring(0, 8)}...${row.apiKey.substring(row.apiKey.length - 4)}` : '-'),
  },
  {
    title: '描述',
    key: 'description',
    width: 200,
    ellipsis: { tooltip: true },
  },
  {
    title: '权限范围',
    key: 'permissions',
    width: 200,
    render: (row) => {
      if (row.permissions && row.permissions.length > 0) {
        return row.permissions.map((perm, index) => {
          const permission = permissionOptions.value.find(p => p.value === perm)
          return h(
            NTag,
            {
              type: 'success',
              style: index > 0 ? 'margin-left: 4px;' : '',
            },
            { default: () => permission ? permission.name : perm },
          )
        })
      }
      return '无权限限制'
    },
  },
  {
    title: 'IP白名单',
    key: 'ipWhitelist',
    width: 150,
    ellipsis: { tooltip: true },
    render: (row) => {
      if (row.ipWhitelist && row.ipWhitelist.length > 0) {
        return h('span', `${row.ipWhitelist.length}个IP`)
      }
      return '无限制'
    },
  },
  {
    title: '过期时间',
    key: 'expireTime',
    width: 180,
    render(row) {
      return h('span', row.expireTime ? formatDateTime(new Date(row.expireTime)) : '永不过期')
    },
  },
  {
    title: '状态',
    key: 'status',
    width: 100,
    render: (row) => {
      const statusMap = {
        ENABLED: { text: '启用', type: 'success' },
        DISABLED: { text: '禁用', type: 'error' },
      }
      const status = statusMap[row.status] || { text: '未知', type: 'default' }
      return h(NTag, { type: status.type }, { default: () => status.text })
    },
  },
  {
    title: '创建时间',
    key: 'createdAt',
    width: 180,
    render(row) {
      return h('span', formatDateTime(new Date(row.createdAt)))
    },
  },
  {
    title: '操作',
    key: 'actions',
    width: 350,
    align: 'right',
    fixed: 'right',
    hideInExcel: true,
    render(row) {
      return [
        h(
          NButton,
          {
            size: 'small',
            type: 'primary',
            secondary: true,
            class: 'ml-12px',
            onClick: () => handleView(row),
          },
          {
            default: () => '查看',
            icon: () => h('i', { class: 'i-carbon:document-view text-14' }),
          },
        ),
        h(
          NButton,
          {
            size: 'small',
            type: 'primary',
            class: 'ml-12px',
            onClick: () => handleEdit(row),
          },
          {
            default: () => '编辑',
            icon: () => h('i', { class: 'i-material-symbols:edit-outline text-14' }),
          },
        ),
        h(
          NButton,
          {
            size: 'small',
            type: 'warning',
            class: 'ml-12px',
            onClick: () => handleRegenerate(row),
          },
          {
            default: () => '重新生成',
            icon: () => h('i', { class: 'i-carbon:reset text-14' }),
          },
        ),
        h(
          NButton,
          {
            size: 'small',
            type: 'error',
            style: 'margin-left: 12px;',
            onClick: () => handleDelete(row.id),
          },
          {
            default: () => '删除',
            icon: () => h('i', { class: 'i-material-symbols:delete-outline text-14' }),
          },
        ),
      ]
    },
  },
]

// 使用统计列配置
const statsColumns = [
  { title: '日期', key: 'date', width: 150, ellipsis: { tooltip: true } },
  {
    title: 'API密钥',
    key: 'apiKeyId',
    width: 200,
    ellipsis: { tooltip: true },
    render: (row) => {
      const apiKey = apiKeysForStats.value.find(k => k.id === row.apiKeyId)
      return apiKey ? apiKey.name : `API密钥${row.apiKeyId}`
    },
  },
  { title: '总请求数', key: 'totalRequests', width: 120, render: row => h('span', formatNumber(row.totalRequests)) },
  { title: '成功请求数', key: 'successfulRequests', width: 120, render: row => h('span', formatNumber(row.successfulRequests)) },
  { title: '失败请求数', key: 'failedRequests', width: 120, render: row => h('span', formatNumber(row.failedRequests)) },
  {
    title: '成功率',
    key: 'successRate',
    width: 120,
    render: (row) => {
      const rate = row.totalRequests > 0 ? (row.successfulRequests / row.totalRequests * 100).toFixed(2) : 0
      return h('span', `${rate}%`)
    },
  },
  {
    title: '平均响应时间',
    key: 'avgResponseTime',
    width: 150,
    render: row => h('span', `${row.avgResponseTime.toFixed(2)}ms`),
  },
  {
    title: '总流量',
    key: 'totalTraffic',
    width: 120,
    render: row => h('span', formatFileSize(row.totalTraffic)),
  },
]

// 处理统计时间范围变化
function handleStatsTimeRangeChange(value) {
  if (value && value.length === 2) {
    statsQueryItems.value.startDate = new Date(value[0]).toISOString()
    statsQueryItems.value.endDate = new Date(value[1]).toISOString()
  }
  else {
    delete statsQueryItems.value.startDate
    delete statsQueryItems.value.endDate
  }
}

// 重新生成API密钥
async function handleRegenerate(row) {
  const d = $dialog.warning({
    content: '确定重新生成API密钥？这将导致当前密钥失效，需要更新所有使用该密钥的应用。',
    title: '警告',
    positiveText: '确定',
    negativeText: '取消',
    async onPositiveClick() {
      try {
        d.loading = true
        await api.regenerateApiKey(row.id)
        $message.success('API密钥重新生成成功')
        d.loading = false
        $table.value?.handleSearch()
      }
      catch (error) {
        console.error(error)
        d.loading = false
        $message.error(error.message || '重新生成失败')
      }
    },
  })
}

function handleView(row) {
  handleOpen({ action: 'view', title: '查看API密钥', row })
}

function handleEdit(row) {
  handleOpen({ action: 'edit', title: '编辑API密钥', row })
}

// 格式化文件大小
function formatFileSize(bytes) {
  if (bytes === 0)
    return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`
}
</script>
